package com.google.code.p.narcissus.coreIntegrationTests;

import junit.framework.Assert;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.google.code.p.narcissus.core.BrowserConfiguration;
import com.google.code.p.narcissus.core.BrowserConfiguration.WindowSize;
import com.google.code.p.narcissus.core.NarcissusException;
import com.google.code.p.narcissus.core.ScreenShooter;
import com.google.code.p.narcissus.core.model.ComparisonResult.PictureComparisonResult;
import com.google.code.p.narcissus.coreIntegrationTests.utils.IntegrationTestConfiguration;
import com.thoughtworks.selenium.SeleneseTestCase;

/**
 * Verifies that taking screenshots of elements in scrollable parents works fine.
 * <p>
 * Most of the time, the size of a document exceeds the size of the window in which it is displayed. When wanting to take screenshots of these, Narcissus will first have to scroll
 * to the element. The complexity comes when the element is located inside scrollable parents. Using javascript, each parent has to be scrolled so that the element will get
 * displayed on screen and "screen-shooted".<br />
 * In case the element itself is bigger than the available space, it will be scrolled multiple times. this test asserts that this part works as well.
 * </p>
 * <p>
 * <b>IMPORTANT NOTE:</b><br />
 * Due to the way Narcissus works, the tiniest difference in rendering will make the tests fail. To make sure you have no problems with the results, make sure you disable "improved
 * font rendering on your OS as well as on the browser you test on (for example, to do this on firefox, follow the following thread):<br />
 * <code>http://superuser.com/questions/267726/how-do-i-disable-font-smoothing-hinting-anti-aliasing-on-firefox-4</code>
 * </p>
 * 
 * @author Jérôme JADOULLE [JADOJ]
 * 
 */
public class ScreenshotsInScrollableElementsIT extends SeleneseTestCase {

	private static final String USER_HOME = System.getProperty("user.home");

	private static final String NARCISSUS_INTEGRATION_TESTS_ROOT = "narcissusIntegrationTests";

	private static final String TEST_NAME = "scrollableElements";

	private static final String TEST_CLASS_NAME = ScreenshotsInScrollableElementsIT.class.getSimpleName();

	private static final String SHOTS_ROOT = USER_HOME + "/" + NARCISSUS_INTEGRATION_TESTS_ROOT;

	@Before
	public void setUp() throws Exception {
		IntegrationTestConfiguration.getInstance().startServer();
		setUp("http://127.0.0.1:9876", "*firefox");
	}

	@After
	public void tearDown() throws Exception {
		IntegrationTestConfiguration.getInstance().startServer();
	}

	/**
	 * Screenshots of elements that are nested into scrollable components.
	 * <p>
	 * Narcissus automatically scrolls the parents of the elements to take a screenshot of. That means that, even if the elements inside the scrolling parents are clipped out of the
	 * display zone at the beginning, correct screenshots will still be taken.
	 * </p>
	 * <p>
	 * The system works whatever the amount of scrollable parents encountered.
	 * </p>
	 * 
	 * @throws NarcissusException
	 */
	@Test
	public void testScreenshotsInScrollableElements() throws NarcissusException {
		// Test specific setup
		ScreenShooter screenShooter = new ScreenShooter(SHOTS_ROOT, TEST_CLASS_NAME, TEST_NAME, selenium);

		// Not strictly necessary. Each Selenium call is separated from the next one by that amount (this is a passthrough to a Selenium property).
		// Can be interesting when wanting to have the tests executed in an understandable manner (i.e. when you are checking the screen as the tests are executed)
		ScreenShooter.setSeleniumSleepInterval(10);
		selenium.open("/");

		// Makes sure that the window will always have the same size when running the tests. A must when the design evolves with page size; Not that important if static.
		BrowserConfiguration.setWindowSize(selenium, WindowSize.Size_1280x1024);

		/*
		 * Actual test happens here:
		 * The first parameter is a Selenium locator pointing to the element you want to take a screenshot of and the second is the name the screenshot will be saved under.
		 * 
		 * You specify an element by Selenium locator => not tied to ids only (id is just the default).
		 * More info here (note that the version of the selenium core are old ones):
		 * - http://release.seleniumhq.org/selenium-remote-control/0.9.2/doc/dotnet/Selenium.html
		 * - http://release.seleniumhq.org/selenium-core/0.8.0/reference.html
		 * 
		 * The screenshot will be saved under the path you initialized when creating the new screenshooter:
		 * [SHOTS_ROOT]/[TEST_CLASS_NAME]/[TEST_NAME]/[SCREENSHOT_NAME]
		 */

		// First test with an element that is present on the page by default and is smaller than the window size:
		screenShooter.verifyGuiElement("narcissusImage", "image");

		// A DIV element containing an image
		Assert.assertEquals(PictureComparisonResult.verificationSuccess, screenShooter.verifyGuiElement("narcissusImage", "image"));

		// Testing with an element that is not on the page by default (must have an element scrolled to have it displayed) and is smaller than the window size:
		screenShooter.verifyGuiElement("Narcissus_in_literature", "text");

		Assert.assertEquals(PictureComparisonResult.verificationSuccess, screenShooter.verifyGuiElement("Narcissus_in_literature", "text"));

	}

}